package lxh.messagebubbleview.view;


import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;

/**
 * Created by liuxh on 2017/8/1.
 */

public class MessageBubbleView extends View {

    private PointF mFixPoint;//固定圆的圆心点
    private PointF mDragPoint;//可拖拽圆的圆心点
    private int mDragRadius=10;//可拖拽圆半径
    private Paint mPaint;

    private int mFixRadiusMax=7;//固定圆初始半径，即最大半径
    private int mFixRadiusMin=3;//固定圆最小半径，小于最小半径时固定圆消失不见
    private int mFixRadiusCurrent;//固定圆当前半径


    public MessageBubbleView(Context context) {
        this(context,null);
    }

    public MessageBubbleView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public MessageBubbleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mPaint=new Paint();
        mPaint.setColor(Color.RED);
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);

        mDragRadius=dipToPx(mDragRadius);
        mFixRadiusMax=dipToPx(mFixRadiusMax);
        mFixRadiusMin=dipToPx(mFixRadiusMin);


    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mDragPoint == null || mFixPoint == null) return;
        //画两个圆，可拖拽圆与固定圆
        //可拖拽圆
        canvas.drawCircle(mDragPoint.x, mDragPoint.y, mDragRadius, mPaint);

        //画贝塞尔路径
        Path bezierPath=getbezierPath();
        if (bezierPath==null)return;
        //固定圆
        double centerDistance = getPointDistance(mDragPoint,mFixPoint);
        mFixRadiusCurrent = (int) (mFixRadiusMax - centerDistance/14);
        if (mFixRadiusCurrent>mFixRadiusMin){
            canvas.drawCircle(mFixPoint.x, mFixPoint.y, mFixRadiusCurrent, mPaint);
            canvas.drawPath(bezierPath,mPaint);
        }
    }

    //有个园，一个固定圆，一个可拖拽圆，固定圆的半径随着与可拖拽圆的距离的增大而变小，小到一定程度消失不见，可拖拽圆半径不变但位置一直变
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                //手指按下，初始化两个圆的圆心心
                float downX=event.getX();
                float downY=event.getY();
                initPoint(downX,downY);
                break;
            case MotionEvent.ACTION_MOVE:
                //移动时更新可拖拽圆的圆心点
                float moveX=event.getX();
                float moveY=event.getY();
                updateDragPoint(moveX,moveY);
                break;
            case MotionEvent.ACTION_UP:
                break;
        }
        invalidate();
        return true;
    }

    /**
     * 更新可拖拽圆的圆心点
     * @param moveX
     * @param moveY
     */
    private void updateDragPoint(float moveX, float moveY) {
        mDragPoint.x=moveX;
        mDragPoint.y=moveY;
    }

    /**
     * 初始化圆心点
     * @param downX
     * @param downY
     */
    private void initPoint(float downX, float downY) {
        mFixPoint=new PointF(downX,downY);
        mDragPoint=new PointF(downX,downY);
    }

    /**
     * dp转px
     * @param dip
     * @return
     */
    private int dipToPx(float dip) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,dip,getResources().getDisplayMetrics());
    }

    /**
     * 计算两圆心之间距离
     * @return
     * @param point1
     * @param point2
     */
    public double getPointDistance(PointF point1, PointF point2) {
        return Math.sqrt(((point1.x-point2.x)*(point1.x-point2.x)+(point1.y-point2.y)*(point1.y-point2.y)));
    }

    /**
     * 画贝塞尔路径
     * @return
     */
    public Path getbezierPath() {
        //求四个点的坐标数学上叫什么忘了，暂全名为，po,p1,p2,p3
        Path bezierPath=new Path();

        //先求角a
        float dy=mDragPoint.y-mFixPoint.y;
        float dx=mDragPoint.x-mFixPoint.x;
        float tanA=dy/dx;
        double arcTanA=Math.atan(tanA);

        float p0x= (float) (mFixPoint.x+mFixRadiusCurrent*Math.sin(arcTanA));
        float p0y= (float) (mFixPoint.y-mFixRadiusCurrent*Math.cos(arcTanA));

        float p1x= (float) (mDragPoint.x+mDragRadius*Math.sin(arcTanA));
        float p1y= (float) (mDragPoint.y-mDragRadius*Math.cos(arcTanA));

        float p2x= (float) (mDragPoint.x-mDragRadius*Math.sin(arcTanA));
        float p2y= (float) (mDragPoint.y+mDragRadius*Math.cos(arcTanA));

        float p3x= (float) (mFixPoint.x-mFixRadiusCurrent*Math.sin(arcTanA));
        float p3y= (float) (mFixPoint.y+mFixRadiusCurrent*Math.cos(arcTanA));

        //拼接贝塞尔路径
        bezierPath.moveTo(p0x,p0y);//移动
        //获取控制点
        PointF controlPoint=getControlPoint();
        //画第一条贝塞尔线，一个控制点(两圆心之间的中心点),一个结束点p1
        bezierPath.quadTo(controlPoint.x,controlPoint.y,p1x,p1y);
        //画第二条贝塞尔线
        bezierPath.lineTo(p2x,p2y);//连接到
        bezierPath.quadTo(controlPoint.x,controlPoint.y,p3x,p3y);
        bezierPath.close();

        return bezierPath;
    }

    /**
     * 获取控制点
     * @return
     */
    public PointF getControlPoint() {
        return new PointF((mDragPoint.x+mFixPoint.x)/2,(mDragPoint.y+mFixPoint.y)/2);
    }
}
